#include "Define/LRG_GridCellContainer.h"

void FLRG_GridCellContainer::Initialize(int32 InNumChunk)
{
	GridCells = new ULRG_Node_GridCell**[InNumChunk];
	FMemory::Memzero(GridCells, sizeof(FUObjectItem*) * InNumChunk);
}

void FLRG_GridCellContainer::SetGridCellCreator(const TFunction<ULRG_Node_GridCell*(const FSpatialCoordinate& Coordinate)>& Function)
{
	GridCellCreator = Function;
}

//TODO,后续需要加锁
ULRG_Node_GridCell* FLRG_GridCellContainer::TryCreateGridCell(const FSpatialCoordinate& Coordinate)
{
	if(!GridCellCreator)
	{
		UE_LOG(LogTemp, Fatal, TEXT("FLRG_GridCellContainer::TryCreateGridCell GridCellCreator"));
		return nullptr;
	}
	const int32 CoordinateId = Coordinate.ToId(CoordinateUpper);
	const int32 ChunkIndex = CoordinateId % NumElementsPerChunk;
	if(ChunkIndex < 0 || ChunkIndex >= NumChunk)
	{
		UE_LOG(LogTemp, Error, TEXT("FLRG_GridCellContainer::TryCreateGridCell %d-%d"), Coordinate.X, Coordinate.Y);
		return nullptr;
	}
	const int32 ElementIndex = CoordinateId - ChunkIndex * NumElementsPerChunk;
	ULRG_Node_GridCell**& Chunk = GridCells[ChunkIndex];
	if(!Chunk)
	{
		Chunk = new ULRG_Node_GridCell*[NumElementsPerChunk];
	}
	ULRG_Node_GridCell*& GridCell = Chunk[ElementIndex];
	if(!GridCell)
	{
		GridCell = GridCellCreator(Coordinate);
	}
	
	return GridCell;
}

ULRG_Node_GridCell* FLRG_GridCellContainer::FindGridCell(const FSpatialCoordinate& Coordinate) const
{
	const int32 CoordinateId = Coordinate.ToId(CoordinateUpper);
	const int32 ChunkIndex = CoordinateId % NumElementsPerChunk;
	if(ChunkIndex < 0 || ChunkIndex >= NumChunk)
	{
		return nullptr;
	}
	ULRG_Node_GridCell**& Chunk = GridCells[ChunkIndex];
	if(!Chunk)
	{
		return nullptr;
	}
	const int32 ElementIndex = CoordinateId - ChunkIndex * NumElementsPerChunk;
	return Chunk[ElementIndex];
}